package com.crawler.crawler.service.impl;

import com.alibaba.fastjson.JSON;
import com.crawler.crawler.domain.Book;
import com.crawler.crawler.domain.BookImportConfig;
import com.crawler.crawler.service.BookImportConfigServer;
import com.crawler.crawler.service.BookService;
import com.crawler.crawler.service.SobookCrawlerServer;
import com.crawler.crawler.util.FileDownload;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * sobook 获取server
 */
@Service
public class SobookCrawlerServerImpl implements SobookCrawlerServer {
    @Autowired
    private BookService bookService;

    @Autowired
    private BookImportConfigServer configServer;

    @Override
    public String sobook() {
        String url = "https://sobooks.cc";
        String filePath = "D:/E/images/";

        //得到页面
        int pages = getPages(url);
        //得到循环起始页面
        BookImportConfig config = configServer.selectBookByName("nowPage");
        int startIndex = Integer.parseInt(config.getValue());

        //根据页面数量循环
        for (int i = startIndex; i <= pages; i++) {
            String childUrl = url;
            if (i > 1) {
                childUrl = url + "/page/" + i;
            }
            //得到图书列表
            List<String> bookUrl = getBookList(childUrl);
            int having=0;
            for (int k = 0; k < bookUrl.size(); k++) {
                Book book = bookService.selectBookByUrl(bookUrl.get(k));
                if (book == null && !bookUrl.get(k).equals("")) {
                    getBookInfo(bookUrl.get(k), i, filePath);
                }
            }
            //将页面数存入数据，以便后期使用
            startIndex++;
            BookImportConfig config1 = new BookImportConfig();
            config1.setId(config.getId());
            config1.setValue(String.valueOf(startIndex));
            configServer.updateConfig(config1);

        }
        return JSON.toJSONString("已完成搜索");
    }


    /**
     * 读取图书页面
     *
     * @param url
     * @param page
     * @param filePath
     */
    @Override
    public void getBookInfo(String url, int page, String filePath) {
        BookImportConfig chromeDriverPath=configServer.selectBookByName("chromeDriverPath");
        System.setProperty("webdriver.chrome.driver", chromeDriverPath.getValue());// chromedriver服务地址
        WebDriver driver = new ChromeDriver(); // 新建一个WebDriver 的对象，但是new 的是谷歌的驱动
        driver.get(url); // 打开指定的网站
        try {
            /**
             * WebDriver自带了一个智能等待的方法。 dr.manage().timeouts().implicitlyWait(arg0, arg1）；
             * Arg0：等待的时间长度，int 类型 ； Arg1：等待时间的单位 TimeUnit.SECONDS 一般用秒作为单位。
             */
            driver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);


            //获取当前浏览器的信息
            System.out.println("Title:" + driver.getTitle());
            System.out.println("currentUrl:" + driver.getCurrentUrl());

            //填写验证码
            try {
                BookImportConfig config1=configServer.selectBookByName("key");
                driver.findElement(By.name("e_secret_key")).sendKeys(config1.getValue());
                driver.findElement(By.className("euc-y-s")).click();
            }catch (Exception e){

            }


            //========================获取图书信息=======================
            //分类
            String cat = driver.findElement(By.xpath("//*[@id=\"mute-category\"]/a")).getAttribute("innerHTML");
            //图片
            String imgUrl = driver.findElement(By.xpath("/html/body/section/div[2]/div/article/div[1]/div[1]/div/div[1]/img")).getAttribute("src");
            //下载图片
            String bookCover = FileDownload.downloadPicture(imgUrl, filePath);

            //书名
            String bookNameStrong = driver.findElement(By.xpath("/html/body/section/div[2]/div/article/div[1]/div[1]/div/div[2]/ul/li[1]")).getAttribute("innerHTML");
            String bookName = bookNameStrong.replaceAll("<strong>书名：</strong>", "");

            //作者
            String authorStrong = driver.findElement(By.xpath("/html/body/section/div[2]/div/article/div[1]/div[1]/div/div[2]/ul/li[2]")).getAttribute("innerHTML");

            String author = authorStrong.replaceAll("<strong>作者：</strong>", "");
            //标签
            String tagsStrong = driver.findElement(By.xpath("/html/body/section/div[2]/div/article/div[1]/div[1]/div/div[2]/ul/li[4]")).getAttribute("innerHTML");
            String tagsStrongs = tagsStrong.replaceAll("<strong>标签：</strong>", "");
            Document document = Jsoup.parse(tagsStrongs);
            Elements elements = document.select("a[href]");

            StringBuilder tagsBuilder = new StringBuilder();
            int elementCount = 1;
            for (Element element : elements) {
                //得到A标签中的文本
                if (elementCount > 1) {
                    tagsBuilder.append(",");
                }
                tagsBuilder.append(element.text());
                elementCount++;
            }
            String tags = tagsBuilder.toString();
            //article-content
            String article = driver.findElement(By.className("article-content")).getAttribute("innerHTML");

            //ISBN
            String isbn = "";
            String regEx1 = "<strong>ISBN：</strong>(\\d){13}";
            Pattern p1 = Pattern.compile(regEx1);
            Matcher m1 = p1.matcher(article);
            if (m1.find()) {
                isbn = m1.group(0);
                isbn = isbn.replace("<strong>ISBN：</strong>", "");
            }
            System.out.println("isbn" + isbn);

            String allHtml = driver.findElement(By.xpath("/html/body/section/div[2]/div/article")).getAttribute("innerHTML");
            String authorValidity = "";
            String contentValidity = "";
            //有内容简介时，则填写内容简介
            if (allHtml.indexOf("<h2>内容简介</h2>") > -1) {
                String articleHtml = allHtml.split("<h2>内容简介</h2>")[1];

                if (articleHtml.indexOf("<h2>作者简介</h2>") > -1) {
                    String[] articleHtml_1 = articleHtml.split("<h2>作者简介</h2>");
                    //内容简介
                    contentValidity = articleHtml_1[0];
                    //作者简介
                    String[] articleHtml_2 = articleHtml_1[1].split("<table class=\"dltable\"><tbody>");
                    authorValidity = articleHtml_2[0];
                } else {
                    //内容简介
                    contentValidity = articleHtml.split("<table class=\"dltable\"><tbody>")[0];
                }
            } else if (allHtml.indexOf("<h2>作者简介</h2>") > -1) {
                String[] articleHtml_1 = allHtml.split("<h2>作者简介</h2>");
                //作者简介
                String[] articleHtml_2 = articleHtml_1[1].split("<table class=\"dltable\"><tbody>");
                authorValidity = articleHtml_2[0];
            }

            String fileSizeHtml = "";
            try {
                fileSizeHtml = driver.findElement(By.xpath("/html/body/section/div[2]/div/article/table/tbody/tr[1]/td[3]")).getAttribute("innerHTML");

            } catch (Exception e) {
                try {
                    fileSizeHtml = driver.findElement(By.xpath("/html/body/section/table/tbody/tr[1]/td[3]")).getAttribute("innerHTML");

                }catch (Exception e1){

                }

            }

            String fileSize="";
            try {
                fileSize = fileSizeHtml.replaceAll("<i class=\"fa fa-th-large\"></i>&nbsp;&nbsp;文件大小：", "");
            }catch (Exception e){

            }

            //百度云盘验证码
            String yunCode = "";
            try {
                String regEx = "提取码：\\w{0,4}";
                Pattern p = Pattern.compile(regEx);
                Matcher m = p.matcher(article);
                if (m.find()) {
                    yunCode = m.group(0);
                    yunCode = yunCode.replace("提取码：", "");
                }
            } catch (Exception e) {

            }


            String baiduyunUrl = "";
            try {
                String articleHtml = allHtml.split("百度网盘：")[1];
                String articleHtml1 = articleHtml.split("提取码")[0];
                Document document1=Jsoup.parse(articleHtml1);
                baiduyunUrl=document1.select("a").attr("href");
            } catch (Exception e) {

            }

            baiduyunUrl = baiduyunUrl.replace("https://sobooks.cc/go.html?url=", "");
            //保存数据到数据库中
            Book book = new Book();
            book.setBookName(bookName);
            book.setBaiduCode(yunCode);
            book.setAuthor(author);
            book.setAuthorValidity(authorValidity);
            book.setCat(cat);
            book.setBaiduUrl(baiduyunUrl);
            book.setBookCover(bookCover);
            book.setIsbn(isbn);
            book.setContentValidity(contentValidity);
            book.setTags(tags);
            book.setFileSize(fileSize);
            book.setUrl(driver.getCurrentUrl());
            book.setFilePath(String.valueOf(page));
            //保存数据
            bookService.insertBook(book);
            driver.quit();
        } catch (Exception e) {
            driver.quit();
            this.sobook();
        }
    }

    /**
     * 读取图书地址
     *
     * @param url
     */
    @Override
    public List<String> getBookList(String url) {
        List<String> bookList = new ArrayList<String>();

        System.setProperty("webdriver.chrome.driver", "D:\\E\\tool\\chromedriver.exe");// chromedriver服务地址
        WebDriver driver = new ChromeDriver(); // 新建一个WebDriver 的对象，但是new 的是谷歌的驱动
//        driver.get(url); // 打开指定的网站
        driver.get(url);// 打开指定的网站        
        try {
            /**
             * WebDriver自带了一个智能等待的方法。 dr.manage().timeouts().implicitlyWait(arg0, arg1）；
             * Arg0：等待的时间长度，int 类型 ； Arg1：等待时间的单位 TimeUnit.SECONDS 一般用秒作为单位。
             */
            driver.manage().timeouts().implicitlyWait(2, TimeUnit.SECONDS);
        } catch (Exception e) {
            e.printStackTrace();
        }

        //获取当前浏览器的信息
        System.out.println("Title:" + driver.getTitle());
        System.out.println("currentUrl:" + driver.getCurrentUrl());

        //获取多个元素
        List<WebElement> element = driver.findElements(By.className("thumb-img"));
        for (WebElement e : element) {
            String bookListHtml = e.getAttribute("innerHTML");
            Document document = Jsoup.parse(bookListHtml);
            //得到第二个a标签数据
            String bookUrl = document.select("a[href]:eq(1)").attr("href");
            bookList.add(bookUrl);
        }
        driver.quit();
        //返回图书地址合集
        return bookList;
    }

    /**
     * 得到页数
     *
     * @param url
     */
    @Override
    public int getPages(String url) {
        System.setProperty("webdriver.chrome.driver", "D:\\E\\tool\\chromedriver.exe");// chromedriver服务地址
        WebDriver driver = new ChromeDriver(); // 新建一个WebDriver 的对象，但是new 的是谷歌的驱动
//        driver.get(url); // 打开指定的网站
        driver.get(url);// 打开指定的网站        
        try {
            /**
             * WebDriver自带了一个智能等待的方法。 dr.manage().timeouts().implicitlyWait(arg0, arg1）；
             * Arg0：等待的时间长度，int 类型 ； Arg1：等待时间的单位 TimeUnit.SECONDS 一般用秒作为单位。
             */
            driver.manage().timeouts().implicitlyWait(2, TimeUnit.SECONDS);
        } catch (Exception e) {
            e.printStackTrace();
        }

        //获取当前浏览器的信息
        System.out.println("Title:" + driver.getTitle());
        System.out.println("currentUrl:" + driver.getCurrentUrl());

        WebElement element = driver.findElement(By.xpath("/html/body/section/div[2]/div/div[2]/ul/li[9]/span"));
        String pagesHtml = element.getAttribute("innerHTML");
        System.out.println(pagesHtml);
        String regEx = "[^0-9]";
        Pattern p = Pattern.compile(regEx);
        Matcher m = p.matcher(pagesHtml);
        String pages = m.replaceAll("").trim();

        //退出
        driver.quit();
        return Integer.parseInt(pages);
    }
}
